/*
Copyright (C) 2013 Johan Ceuppens

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#import "SignalC.h"
#import "Slot.h"
#import "Trackable.h"

__SIGCM_RETURNTYPEIMP(SIGCMReturnType, - (void *)get { return data; }  - (void) set:(void*)type { data = type; }  )
__SIGCM_TYPEIMP(SIGCMType, - (SIGCMType *)get { return data; }  - (void) set:(SIGCMType*)type { data = type; }  )

@implementation SignalCBase

- (id) init 
{
	slotlist = [NSMutableArray new];
	iterator = [slotlist objectEnumerator];

	return (self); 
}

@end

@implementation SignalC0 
- (id) SignalC0:(SIGCMReturnType*)returntype
{
	[super init];
	returnType = returntype;
	return self;
}

- (void)connect:(id)funptr
{
	//FIXMENOTE use isKindOfClass:
	if ([funptr className] == @"Functor")
		[slotlist addObject:[[Slot alloc] init:funptr blocked:false]];
	else if ([funptr className] == @"Slot")
		[slotlist addObject:funptr];
	else
		NSLog(@"SignalC0 connect - Unknown Slot Type");
}

- (SIGCMReturnType*)emit:(NSMutableArray*)a
{
	id object;
	if (!(object = [iterator nextObject])) {
		[iterator dealloc];//FIXMENOTE set to begin
		iterator = [slotlist objectEnumerator];
	}

 	if (![object blocked])
		returnType = [object callit:a];//FIXME

	return returnType;
}

@end

@implementation SignalC1
- (id) SignalC1:(SIGCMReturnType*)returntype Arg1:(SIGCMType*)argtype1
{

	[super init];
	returnType = returntype;
	argType1 = argtype1;
	return self;
}

- (void)connect:(id)funptr
{
	[slotlist addObject:[[Slot alloc] init:funptr blocked:false]];
}

- (SIGCMReturnType*)emit:(NSMutableArray*)a//(SIGCMType*)arg0
{
	id object;
	if (!(object = [iterator nextObject])) {
		[iterator dealloc];//FIXMENOTE set to begin
		iterator = [slotlist objectEnumerator];
	}

 	if (![object blocked])
		returnType = [object callit:a];//FIXME

	return returnType;
}

@end

@implementation SignalC2
- (id) SignalC1:(SIGCMReturnType*)returntype Arg1:(SIGCMType*)argtype1 Arg2:(SIGCMType*)argtype2
{

	[super init];
	returnType = returntype;
	argType1 = argtype1;
	argType2 = argtype2;
	return self;
}

- (void)connect:(id)funptr
{
	[slotlist addObject:[[Slot alloc] init:funptr blocked:false]];
}

- (SIGCMReturnType*)emit:(NSMutableArray*)a//(SIGCMType*)arg0 arg1:(SIGCMType*)arg1
{
	id object;
	if (!(object = [iterator nextObject])) {
		[iterator dealloc];//FIXMENOTE set to begin
		iterator = [slotlist objectEnumerator];
	}

 	if (![object blocked])
		returnType = [object callit:a];	

	return returnType;
	
}

@end



